home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / facilis2.arc / BLOCK.PAS next >
Pascal/Delphi Source File  |  1991-04-28  |  44KB  |  1,500 lines

  1. { Facilis 0.31                                   file: BLOCK.PAS      }
  2.  
  3. overlay procedure blockov(fsys: symset; isfun: boolean; level: integer);
  4.  
  5. type   item = record
  6.                 typ: types; ref: index; temp: boolean
  7.               end;
  8.      conrec = record case tp: types of
  9.                        ints,chars,bools: (i:integer);
  10.                        reals: (r: real)
  11.                      end ;
  12.  
  13. var    dx : integer;    { data allocation index }
  14.        prt: integer;    { t-index of this procedure }
  15.        prb: integer;    { b-index of this procedure }
  16.        x  : integer;
  17.  
  18.   procedure skip(fsys: symset; n: integer);
  19.  
  20.   begin
  21.     error(n); skipflag := true;
  22.     while not (sy in fsys) do insymbol;
  23.     if skipflag then endskip
  24.   end  { skip } ;
  25.  
  26.   procedure test(s1,s2: symset; n: integer);
  27.  
  28.   begin
  29.     if not (sy in s1) then skip(s1+s2,n)
  30.   end  {test } ;
  31.  
  32.   procedure testsemicolon;
  33.  
  34.   begin
  35.     if sy = semicolon
  36.     then insymbol
  37.     else begin
  38.       error(14);
  39.       if sy in [comma,colon] then insymbol
  40.     end ;
  41.     test([ident]+blockbegsys, fsys, 6)
  42.   end  { testsemicolon } ;
  43.  
  44.   procedure enter(id: alfa; k:object);
  45.  
  46.   var    j,l: integer;
  47.   begin
  48.     if t = tmax
  49.     then fatal(1)
  50.     else begin
  51.       tab[0].name := id;
  52.       j := btab[display[level]].last;  l := j;
  53.       while tab[j].name <> id do  j := tab[j].link;
  54.       if j <> 0
  55.       then error(1)
  56.       else begin
  57.         t := t+1;
  58.         with tab[t] do
  59.         begin
  60.           name:= id;   link := l;
  61.           obj := k;     typ := notyp;   ref := 0;
  62.           lev := level; adr := 0
  63.         end ;
  64.         btab[display[level]].last := t
  65.       end
  66.     end
  67.   end  { enter } ;
  68.  
  69.   function loc(id: alfa): integer;
  70.  
  71.   var    i,j: integer;      { locate id in tabel }
  72.   begin
  73.     i := level; tab[0].name := id;    { sentinel }
  74.     repeat
  75.       j := btab[display[i]].last;
  76.       while tab[j].name <> id do  j := tab[j].link;
  77.       i := i-1;
  78.     until (i<0) or (j<>0);
  79.     if j = 0 then error(0);
  80.     loc := j
  81.   end  { loc } ;
  82.  
  83.   procedure entervariable;
  84.  
  85.   begin
  86.     if sy = ident
  87.     then begin
  88.       enter(id,vvariable); insymbol
  89.     end else error(2)
  90.   end  { entervariable } ;
  91.  
  92.   procedure constant(fsys: symset; var c: conrec);
  93.  
  94.   var    x, sign: integer;
  95.   begin
  96.     c.tp := notyp; c.i := 0;
  97.     test(constbegsys, fsys, 50);
  98.     if sy in constbegsys
  99.     then begin
  100.       if sy = charcon
  101.       then begin
  102.         c.tp := chars; c.i := inum;
  103.         insymbol
  104.       end else
  105.       if sy = stringcon
  106.       then begin
  107.         c.tp := strngs;
  108.         c.i := seg(spnt^);
  109.         insymbol
  110.       end else begin
  111.         sign := 0;
  112.         if sy in [plus,minus]
  113.         then begin
  114.           if sy = minus then sign := -1 else sign := 1;
  115.           insymbol
  116.         end ;
  117.         if sy = ident
  118.         then begin
  119.           x := loc(id);
  120.           if x <> 0
  121.           then if tab[x].obj <> konstant
  122.                then error(25)
  123.                else begin
  124.                  c.tp := tab[x].typ;
  125.                  if c.tp in [ints,reals] then
  126.                    if sign=0 then sign := 1;
  127.                  if c.tp = reals
  128.                  then c.r := sign*rconst[tab[x].adr]
  129.                  else if c.tp = ints
  130.                  then c.i := sign*tab[x].adr
  131.                  else begin
  132.                    if sign<>0 then error(33);
  133.                    c.i := tab[x].adr
  134.                  end
  135.                end ;
  136.           insymbol
  137.         end else begin
  138.           if sign=0 then sign := 1;
  139.           if sy = intcon
  140.             then begin
  141.               c.tp := ints; c.i := sign*inum;
  142.               insymbol
  143.             end else if sy = realcon
  144.                      then begin
  145.                        c.tp := reals; c.r := sign*rnum;
  146.                        insymbol
  147.                      end else skip(fsys,50)
  148.         end
  149.       end;
  150.       test(fsys,[], 6)
  151.     end
  152.   end  { constant } ;
  153.  
  154.   procedure typ(fsys: symset; var tp: types; var rf, sz: integer);
  155.  
  156.   var    eltp: types;
  157.          elrf,elsz,offset,x,t0,t1: integer;
  158.         dummy: conrec;
  159.  
  160.     procedure arraytyp(var aref,arsz: integer);
  161.  
  162.     var    eltp: types;
  163.            low, high: conrec;
  164.            elrf, elsz: integer;
  165.     begin
  166.       constant([twodots,rbrack,rparent,ofsy]+fsys, low);
  167.       if low.tp in [reals,strngs]
  168.       then  begin
  169.         error(27);
  170.         low.tp := ints; low.i := 0
  171.       end ;
  172.       if sy = twodots then insymbol else error(13);
  173.       constant([rbrack,comma,rparent,ofsy]+fsys, high);
  174.       if high.tp <> low.tp
  175.       then begin
  176.         error(27); high.i := low.i
  177.       end ;
  178.       enterarray(low.tp, low.i,high.i);
  179.       aref := a;
  180.       if sy = comma
  181.       then begin
  182.         insymbol;
  183.         eltp := arrays;
  184.         arraytyp(elrf,elsz)
  185.       end else begin
  186.         if sy = rbrack
  187.         then insymbol
  188.         else begin
  189.           error(12);
  190.           if sy = rparent then insymbol
  191.         end ;
  192.         if sy = ofsy then insymbol else error(8);
  193.         typ(fsys,eltp,elrf,elsz)
  194.       end ;
  195.  
  196.       with atab[aref] do
  197.       begin
  198.         arsz := (high-low+1)*elsz; size := arsz;
  199.         if arsz > stacksize then error(61);
  200.         eltyp := eltp; elref := elrf; elsize := elsz
  201.       end ;
  202.     end  {arraytyp } ;
  203.  
  204.   begin  { typ }
  205.     tp := notyp; rf := 0; sz := 0;
  206.     if sy = packedsy
  207.     then begin
  208.       insymbol;
  209.       if not (sy = arraysy) or (sy = recordsy)
  210.       then error(10);
  211.     end;
  212.     test(typebegsys,fsys, 10);
  213.     if sy in typebegsys
  214.     then begin
  215.       if sy = ident
  216.       then begin
  217.         x := loc(id);
  218.         if x <> 0
  219.         then with tab[x] do
  220.                if obj <> type1
  221.                then error(29)
  222.                else begin
  223.                  tp := typ; rf := ref; sz := adr;
  224.                  if tp = notyp then error(30)
  225.                end ;
  226.         insymbol;
  227.         if (tp=strngs) and (sy=lbrack)
  228.         then begin
  229.           insymbol;
  230.           constant([rbrack]+fsys,dummy);
  231.           if sy=rbrack then insymbol else error(12);
  232.         end;
  233.       end else if sy = arraysy
  234.                then begin
  235.                  insymbol;
  236.                  if sy = lbrack
  237.                  then insymbol
  238.                  else begin
  239.                    error(11);
  240.                    if sy = lparent
  241.                    then insymbol
  242.                  end ;
  243.                  tp := arrays; arraytyp(rf,sz)
  244.                end else begin  { records }
  245.                  insymbol;
  246.                  enterblock;
  247.                  tp := records; rf := b;
  248.                  if level = lmax then fatal(5);
  249.                  level := level+1; display[level] := b; offset := 0;
  250.                  while not (sy in fsys-[semicolon,comma,ident]+[endsy]) do
  251.                  begin  { field section }
  252.                    if sy = ident
  253.                    then begin
  254.                      t0 := t; entervariable;
  255.                      while sy = comma do
  256.                      begin
  257.                        insymbol; entervariable;
  258.                      end ;
  259.                      if sy = colon then insymbol else error(5);
  260.                      t1 := t;
  261.                      typ(fsys+[semicolon,endsy,comma,ident],eltp,elrf,elsz);
  262.                      while t0 < t1 do
  263.                      begin
  264.                        t0 := t0+1;
  265.                        with tab[t0] do
  266.                        begin
  267.                          typ := eltp;
  268.                          ref := elrf;   normal := true;
  269.                          adr := offset; offset := offset + elsz
  270.                        end
  271.                      end
  272.                    end ; {sy = ident}
  273.                    if sy <> endsy
  274.                    then begin
  275.                      if sy = semicolon
  276.                      then insymbol
  277.                      else begin
  278.                        error(14);
  279.                        if sy = comma then insymbol
  280.                      end ;
  281.                      test([ident,endsy,semicolon], fsys, 6)
  282.                    end
  283.                  end ; {field section}
  284.  
  285.                  btab[rf].vsize := offset; sz := offset;
  286.                  if sz > stacksize then error(61);
  287.                  btab[rf].psize := 0;
  288.                  insymbol; level := level-1
  289.                end ; {records}
  290.       test(fsys, [], 6)
  291.     end
  292.   end  { typ } ;
  293.  
  294.   procedure parameterlist;      { formal parameter list }
  295.  
  296.   var    tp    : types;
  297.          valpar: boolean;
  298.          rf,sz, x, t0: integer;
  299.   begin
  300.     insymbol;
  301.     tp := notyp; rf := 0; sz := 0;
  302.     test([ident, varsy], fsys+[rparent], 7);
  303.     while sy in [ident, varsy] do
  304.     begin
  305.       if sy <> varsy
  306.       then valpar := true
  307.       else begin
  308.         insymbol;
  309.         valpar := false
  310.       end ;
  311.       t0 := t; entervariable;
  312.       while sy = comma do
  313.       begin
  314.         insymbol; entervariable;
  315.       end;
  316.       if sy = colon
  317.       then begin
  318.         insymbol;
  319.         if sy <> ident
  320.         then error(2)
  321.         else begin
  322.           x := loc(id); insymbol;
  323.           if x <> 0
  324.           then with tab[x] do
  325.                if obj <> type1
  326.                then error(29)
  327.                else begin
  328.                  tp := typ;   rf := ref;
  329.                  if valpar then sz := adr else sz := 1
  330.                end ;
  331.           end ;
  332.         test([semicolon,rparent], [comma,ident]+fsys, 14)
  333.       end else error(5);
  334.       while t0 < t do
  335.       begin
  336.         t0 := t0+1;
  337.         with tab[t0] do
  338.         begin
  339.           typ := tp; ref := rf;
  340.           adr := dx; lev := level;
  341.           normal := valpar;
  342.           dx := dx + sz
  343.         end
  344.       end ;
  345.       if sy <> rparent
  346.       then begin
  347.         if sy = semicolon
  348.         then insymbol
  349.         else begin
  350.           error(14);
  351.           if sy = comma then insymbol
  352.         end ;
  353.         test([ident,varsy], [rparent]+fsys, 6)
  354.       end
  355.     end  { while } ;
  356.  
  357.     if sy = rparent
  358.     then begin
  359.       insymbol;
  360.       test([semicolon,colon], fsys, 6)
  361.     end else error(4)
  362.   end  { parameterlist } ;
  363.  
  364.   procedure     constdec;
  365.  
  366.   var    c: conrec;
  367.   begin
  368.     insymbol;
  369.     test([ident], blockbegsys, 2);
  370.     while sy = ident do
  371.     begin
  372.       enter(id,konstant); insymbol;
  373.       if sy = eql
  374.       then insymbol
  375.       else begin
  376.         error(16);
  377.         if sy = becomes then insymbol
  378.       end ;
  379.       constant([semicolon,comma,ident]+fsys,c);
  380.       tab[t].typ := c.tp;
  381.       tab[t].ref := 0;
  382.       if c.tp = reals
  383.       then begin
  384.         enterreal(c.r); tab[t].adr := c1
  385.       end else tab[t].adr := c.i;
  386.       testsemicolon
  387.     end
  388.   end  { constdec } ;
  389.  
  390.   procedure typedeclaration;
  391.  
  392.   var    tp: types;
  393.          rf, sz, t1: integer;
  394.   begin
  395.     insymbol;
  396.     test([ident], blockbegsys, 2);
  397.     while sy = ident do
  398.     begin
  399.       enter(id,type1);
  400.       t1 := t; insymbol;
  401.       if sy = eql
  402.       then insymbol
  403.       else begin
  404.         error(16);
  405.         if sy = becomes then insymbol
  406.       end ;
  407.       typ([semicolon,comma,ident]+fsys, tp, rf, sz);
  408.       with tab[t1] do
  409.       begin
  410.         typ := tp; ref := rf; adr := sz
  411.       end;
  412.       testsemicolon
  413.     end
  414.   end  { typedeclaration } ;
  415.  
  416.   procedure variabledeclaration;
  417.  
  418.   var    tp: types;
  419.          t0, t1, rf, sz: integer;
  420.   begin
  421.     insymbol;
  422.     while sy = ident do
  423.     begin
  424.       t0 := t; entervariable;
  425.       while sy = comma do
  426.       begin
  427.         insymbol; entervariable;
  428.       end ;
  429.       if sy = colon then insymbol else error(5);
  430.       t1 := t;
  431.       typ([semicolon,comma,ident]+fsys, tp, rf, sz);
  432.       while t0 < t1 do
  433.       begin
  434.         t0 := t0+1;
  435.         with tab[t0] do
  436.         begin
  437.           typ := tp;    ref := rf;
  438.           lev := level; adr := dx;
  439.           normal := true;
  440.           dx := dx + sz
  441.         end
  442.       end ;
  443.       testsemicolon
  444.     end
  445.   end  { variabledeclaration } ;
  446.  
  447.   procedure procdeclaration;
  448.  
  449.   var    isfun: boolean;
  450.   begin
  451.     isfun := sy = funcsy;
  452.     insymbol;
  453.     if sy <> ident
  454.     then begin
  455.       error(2); id := '          '
  456.     end;
  457.     if isfun then enter(id,funktion) else enter(id,prozedure);
  458.     tab[t].normal := true;
  459.     insymbol;
  460.     block([semicolon]+fsys, isfun, level+1);
  461.     if sy = semicolon then insymbol else error(14);
  462.     emit(132+ord(isfun))     { exit }
  463.   end  { procdeclaration } ;
  464.  
  465.   procedure statement(fsys: symset);
  466.  
  467.   var    i: integer;
  468.          x: item;
  469.  
  470.     procedure expression(fsys: symset; var x: item); forward;
  471.  
  472.     procedure selector(fsys: symset; var v: item);
  473.  
  474.     var    x: item;
  475.            a,j: integer;
  476.     begin  { sy in [lparent, lbrack, period] }
  477.       repeat
  478.         if sy = period
  479.         then begin
  480.           insymbol;   { field selector }
  481.           if sy <> ident
  482.           then error(2)
  483.           else begin
  484.             if v.typ <> records
  485.             then error(31)
  486.             else begin  {search field identifier }
  487.               j := btab[v.ref].last;
  488.               tab[0].name := id;
  489.               while tab[j].name <> id do j := tab[j].link;
  490.               if j = 0 then error(0);
  491.               v.typ := tab[j].typ;
  492.               v.ref := tab[j].ref;
  493.               a := tab[j].adr;
  494.               if a <> 0 then emit1(9,a)
  495.             end ;
  496.             insymbol
  497.           end
  498.         end else begin  { array selector }
  499.           if sy <> lbrack then error(11);
  500.           if v.typ=strngs then begin
  501.             insymbol;
  502.             expression(fsys+[rbrack],x);
  503.             if x.typ<>ints then error(34) else emit(165);
  504.             v.typ := chars
  505.           end else
  506.           repeat
  507.             insymbol;
  508.             expression(fsys+[comma,rbrack], x);
  509.             if v.typ <> arrays
  510.             then error(28)
  511.             else begin
  512.               a := v.ref;
  513.               if atab[a].inxtyp <> x.typ
  514.               then error(26)
  515.               else if atab[a].elsize = 1
  516.                    then emit1(20,a)
  517.                    else emit1(21,a);
  518.               v.typ := atab[a].eltyp;
  519.               v.ref := atab[a].elref
  520.             end
  521.           until sy <> comma;
  522.  
  523.           if sy = rbrack
  524.           then insymbol
  525.           else begin
  526.             error(12);
  527.             if sy = rparent then insymbol
  528.           end
  529.         end
  530.       until not (sy in [lbrack,lparent,period]);
  531.  
  532.       test (fsys, [], 6)
  533.     end  { selector } ;
  534.  
  535.     procedure call(fsys: symset; i: integer);
  536.  
  537.     var    x: item;
  538.            lastp, cp, k: integer;
  539.  
  540.     begin
  541.       emit1(18,i);   { mark stack }
  542.       lastp := btab[tab[i].ref].lastpar;
  543.       cp := i;
  544.       if sy = lparent
  545.       then begin  { actual parameter list }
  546.         repeat
  547.           insymbol;
  548.           if cp >= lastp
  549.           then error(39)
  550.           else begin
  551.             cp := cp+1;
  552.             if tab[cp].normal
  553.             then begin  {value parameter }
  554.               expression(fsys+[comma,colon,rparent], x);
  555.               if x.typ=tab[cp].typ
  556.               then begin
  557.                 if x.ref <> tab[cp].ref
  558.                 then error(36)
  559.                 else if x.typ = arrays
  560.                      then emit1(22,atab[x.ref].size)
  561.                 else if x.typ = records
  562.                      then emit1(22,btab[x.ref].vsize)
  563.                 else if x.typ = strngs
  564.                      then if x.temp then emit(173)
  565.                                     else emit(172)
  566.               end else if (x.typ=ints) and (tab[cp].typ=reals)
  567.                        then emit1(26,0)
  568.                        else if x.typ<>notyp then error(36);
  569.             end else begin  { var parameter }
  570.               if sy <> ident
  571.               then error(2)
  572.               else begin
  573.                 k := loc(id);
  574.                 insymbol;
  575.                 if k <> 0
  576.                 then begin
  577.                   if tab[k].obj <> vvariable then error(37);
  578.                   x.typ := tab[k].typ;
  579.                   x.ref := tab[k].ref;
  580.                   if tab[k].normal
  581.                   then emit2(0,tab[k].lev,tab[k].adr)
  582.                   else emit2(1,tab[k].lev,tab[k].adr);
  583.                   if sy in [lbrack,lparent,period]
  584.                   then begin
  585.                     if x.typ=strngs then error(60);
  586.                     selector(fsys+[comma,colon,rparent], x);
  587.                   end;
  588.                   if (x.typ<>tab[cp].typ) or (x.ref<>tab[cp].ref)
  589.                   then error(36)
  590.                 end
  591.               end
  592.             end {var parameter}
  593.           end ;
  594.           test([comma,rparent], fsys, 6)
  595.         until sy <> comma;
  596.  
  597.         if sy = rparent then insymbol else error(4)
  598.       end ;
  599.  
  600.       if cp < lastp then error(39);  { too few actual parameters }
  601.       emit1(19, btab[tab[i].ref].psize-1);
  602.       if tab[i].lev < level then emit2(3, tab[i].lev, level)
  603.     end  { call } ;
  604.  
  605.     function resulttype(a,b: types): types;
  606.  
  607.     begin
  608.       if (a>reals) or (b>reals)
  609.       then begin
  610.         error(33);
  611.         resulttype := notyp
  612.       end else if (a=notyp) or (b=notyp)
  613.                then resulttype := notyp
  614.                else if a=ints
  615.                     then if b=ints
  616.                          then resulttype := ints
  617.                          else begin
  618.                            resulttype := reals; emit1(26,1)
  619.                          end
  620.                     else begin
  621.                       resulttype := reals;
  622.                       if b=ints then emit1(26,0)
  623.                     end
  624.     end   { resulttype } ;
  625.  
  626.     procedure expression {fsys:symset; var x:item};
  627.  
  628.     var    y :item;
  629.            op:symbol;
  630.            t :integer;
  631.  
  632.       procedure simpleexpression(fsys:symset; var x:item);
  633.  
  634.       var    y :item;
  635.              op:symbol;
  636.              t :integer;
  637.  
  638.         procedure term(fsys:symset; var x:item);
  639.  
  640.         var    y :item;
  641.                op:symbol;
  642.                ts:typset;
  643.  
  644.           procedure factor(fsys:symset; var x:item);
  645.  
  646.           var    i,f: integer;
  647.  
  648.             procedure standfct(n: integer);
  649.  
  650.             var    ts: typset;
  651.  
  652.             begin { standard function no. n }
  653.             if n in [19,39,47,48,49]
  654. { maxavail,keypressed,inkey,wherex,wherey }
  655.             then emit1(8,n)
  656. { random }  else if (n=40) and (sy <> lparent)
  657.                  then begin
  658.                    emit1(8,n+1);
  659.                    x.typ := reals; end
  660.             else begin
  661.               if sy = lparent
  662.               then insymbol
  663.               else error(9);
  664.               if (n < 17) or (n > 19)
  665.               then begin
  666.                 expression(fsys+[comma,rparent],x);
  667.  
  668.                 case n of
  669.  
  670.  { abs,sqr }    0,2: begin
  671.                        ts := [ints,reals];
  672.                        tab[i].typ := x.typ;
  673.                        if x.typ = reals then n := n+1
  674.                      end;
  675.  
  676.  { odd,chr }    4,5: ts := [ints];
  677.  
  678.  { ord }          6: ts := [ints,bools,chars];
  679.  
  680.  { succ,pred }  7,8: begin
  681.                        ts := [ints,bools,chars];
  682.                        tab[i].typ := x.typ
  683.                      end;
  684.  
  685.  { round,trunc } 9,10,11,12,13,14,15,16:
  686.  { sin,cos,... }     begin
  687.                        ts := [ints,reals];
  688.                        if x.typ = ints then emit1(26,0)
  689.                      end;
  690.  
  691.  { length }      20: begin
  692.                        ts := [strngs,chars];
  693.                        if x.temp then n := n+1;
  694.                        if x.typ = chars then n := n+2
  695.                      end;
  696.  
  697.  { copy }        23: begin
  698.                        ts := [strngs,chars];
  699.                        if x.typ = chars then n := n+2
  700.                          else if x.temp then n := n+1;
  701.                        test([comma], [comma,rparent]+fsys, 59);
  702.                        if sy = comma then begin
  703.                          insymbol;
  704.                          expression(fsys+[comma,rparent],y);
  705.                          if y.typ <> ints
  706.                            then if y.typ <> notyp then error(34);
  707.                          test([comma,rparent], fsys, 6);
  708.                          if sy = comma then begin
  709.                            insymbol;
  710.                            expression(fsys+[rparent],y);
  711.                            if y.typ <> ints
  712.                              then if y.typ <> notyp then error(34);
  713.                          end else emit1(24,nmax);
  714.                        end;
  715.                      end;
  716.  
  717. { pos }          26: begin
  718.                        ts := [strngs,chars];
  719.                        if x.typ = chars then n := n+2
  720.                          else if x.temp then n := n+1;
  721.                        test([comma], [comma]+fsys, 59);
  722.                        if sy = comma then begin
  723.                          insymbol;
  724.                          expression(fsys+[rparent],y);
  725.                          if y.typ <> strngs
  726.                          then if y.typ <> notyp then error(38) else
  727.                          else if y.temp then n := n+4;
  728.                        end
  729.                      end;
  730.  
  731. { str }          33: begin
  732.                        ts := [ints,reals];
  733.                        if x.typ = reals then n := n+1
  734.                      end;
  735.  
  736. { val,rval }  35,37: begin
  737.                        ts := [strngs];
  738.                        if x.temp then n := n+1
  739.                      end;
  740.  
  741. { random }       40: ts := [ints];
  742.  
  743. { upcase }       42: ts := [chars];
  744.  
  745.                 end ; { case }
  746.  
  747.                 if x.typ in ts
  748.                 then emit1(8,n)
  749.                 else if x.typ <> notyp
  750.                      then error(48);
  751.               end else begin    { n in [17,18] }
  752.                 if sy <> ident
  753.                 then error(2)
  754.                 else if id <> 'input     '
  755.                      then error(0)
  756.                      else insymbol;
  757.                 emit1(8,n);
  758.               end ;
  759.               x.typ := tab[i].typ; x.temp := true;
  760.               if sy = rparent then insymbol else error(4)
  761.             end end { standfct } ;
  762.  
  763.           begin  { factor }
  764.             x.typ := notyp;
  765.             x.ref := 0;
  766.             test(facbegsys, fsys, 58);
  767.             while sy in facbegsys do begin
  768.             case sy of
  769.        ident: begin
  770.                 i := loc(id);
  771.                 insymbol;
  772.                 with tab[i] do
  773.  
  774.                   case obj of
  775.  
  776.           konstant: begin
  777.                       x.typ := typ;
  778.                       x.ref := 0; x.temp := false;
  779.                       if x.typ = reals
  780.                       then emit1(25,adr)
  781.                       else emit1(24,adr)
  782.                     end ;
  783.  
  784.          vvariable: begin
  785.                       x.typ := typ;
  786.                       x.ref := ref; x.temp := false;
  787.                       if sy in [lbrack,lparent,period]
  788.                       then begin
  789.                         if normal then f := 0 else f := 1;
  790.                         if x.typ=strngs then begin
  791.                           emit2(f+1,lev,adr);
  792.                           selector(fsys,x);  end
  793.                         else begin
  794.                           emit2(f,lev,adr);
  795.                           selector(fsys,x);
  796.                           if x.typ in stantyps then emit(134);
  797.                         end
  798.                       end else begin
  799.                         if x.typ in stantyps
  800.                         then if normal
  801.                              then f := 1
  802.                              else f := 2
  803.                         else if normal then f := 0 else f :=1;
  804.                         emit2(f, lev, adr)
  805.                       end
  806.                     end ;
  807.  
  808.   type1, prozedure: error(44);
  809.  
  810.          funktion : begin
  811.                       x.typ := typ; x.temp := true;
  812.                       if lev <> 0
  813.                       then call(fsys, i)
  814.                       else standfct(adr)
  815.                     end
  816.  
  817.                   end  { case obj, with }
  818.                 end;   { ident }
  819.  
  820.      realcon: begin
  821.                 x.typ := reals; x.ref := 0;
  822.                 enterreal(rnum);
  823.                 emit1(25, c1);
  824.                 insymbol
  825.               end;
  826.      charcon: begin
  827.                 x.typ := chars; x.ref := 0; x.temp := false;
  828.                 emit1(24, inum);
  829.                 insymbol
  830.               end;
  831.       intcon: begin
  832.                 x.typ := ints; x.ref := 0;
  833.                 emit1(24, inum);
  834.                 insymbol
  835.               end;
  836.    stringcon: begin
  837.                 x.typ := strngs; x.ref := 0; x.temp := false;
  838.                 emit1(24,seg(spnt^));
  839.                 insymbol
  840.               end;
  841.      lparent: begin
  842.                 insymbol;
  843.                 expression(fsys+[rparent], x);
  844.                 if sy = rparent
  845.                 then insymbol
  846.                 else error(4)
  847.               end;
  848.        notsy: begin
  849.                 insymbol;
  850.                 factor(fsys,x);
  851.                 if x.typ=bools
  852.                 then emit(135)
  853.                 else if x.typ<>notyp
  854.                      then error(32)
  855.               end;
  856.             end;  { case sy }
  857.             test(fsys, facbegsys, 6);
  858.             end { while }
  859.           end { factor } ;
  860.  
  861.         begin { term }
  862.           factor(fsys+[times,rdiv,idiv,imod,andsy], x);
  863.           while sy in [times,rdiv,idiv,imod,andsy] do
  864.           begin
  865.             op := sy;
  866.             insymbol;
  867.             factor(fsys+[times,rdiv,idiv,imod,andsy], y);
  868.             if op = times
  869.             then begin
  870.               x.typ := resulttype(x.typ, y.typ);
  871.  
  872.               case x.typ of
  873.          notyp: ;
  874.          ints : emit(157);
  875.          reals: emit(160);
  876.               end
  877.  
  878.             end else if op = rdiv
  879.                      then begin
  880.                        if x.typ = ints
  881.                        then begin
  882.                          emit1(26,1);
  883.                          x.typ := reals
  884.                        end ;
  885.                        if y.typ = ints
  886.                        then begin
  887.                          emit1(26,0);
  888.                          y.typ := reals
  889.                        end ;
  890.                        if (x.typ=reals) and (y.typ=reals)
  891.                        then emit(161)
  892.                        else begin
  893.                          if (x.typ<>notyp) and (y.typ<>notyp)
  894.                          then error(33);
  895.                          x.typ := notyp
  896.                        end
  897.                      end else
  898.                        if op = andsy
  899.                        then begin
  900.                          if (x.typ=bools) and (y.typ=bools)
  901.                          then emit(156)
  902.                          else begin
  903.                            if (x.typ<>notyp) and (y.typ<>notyp)
  904.                            then error(32);
  905.                            x.typ := notyp
  906.                          end
  907.                        end else begin     { op in [idiv,imod] }
  908.                          if (x.typ=ints) and (y.typ=ints)
  909.                          then if op=idiv
  910.                               then emit(158)
  911.                               else emit(159)
  912.                          else begin
  913.                            if (x.typ<>notyp) and (y.typ<>notyp)
  914.                            then error(34);
  915.                            x.typ := notyp
  916.                          end
  917.                        end
  918.           end {while}
  919.         end { term } ;
  920.  
  921.       begin { simpleexpression }
  922.         if sy in [plus,minus]
  923.         then begin
  924.           op := sy;
  925.           insymbol;
  926.           term(fsys+[plus,minus], x);
  927.           if x.typ > reals
  928.           then error(33)
  929.           else if op = minus
  930.                then if x.typ = reals
  931.                     then emit(164)
  932.                     else emit(136)
  933.         end else term(fsys+[plus,minus,orsy], x);
  934.         while sy in [plus,minus,orsy] do
  935.         begin
  936.           op := sy;
  937.           insymbol;
  938.           term(fsys+[plus,minus,orsy], y);
  939.           if op = orsy
  940.           then begin
  941.             if (x.typ=bools) and (y.typ=bools)
  942.             then emit(151)
  943.             else begin
  944.               if (x.typ <> notyp) and (y.typ<>notyp)
  945.               then error(32);
  946.               x.typ := notyp
  947.             end
  948.           end else if (x.typ = chars) or (x.typ = strngs)
  949.           then begin
  950.             if not((y.typ = chars) or (y.typ = strngs))
  951.             then begin error(38);
  952.                    x.typ := notyp; end
  953.             else begin
  954.                    if x.typ = chars then t := 0 else t := 1;
  955.                    if y.typ = strngs then t := t+2;
  956.                    if x.temp then t := t+4;
  957.                    if y.temp then t := t+8;
  958.                    emit1(7,t);
  959.                    x.typ := strngs; x.temp := true;
  960.                  end
  961.             end
  962.           else begin
  963.             x.typ := resulttype(x.typ, y.typ);
  964.  
  965.             case x.typ of
  966.        notyp: ;
  967.        ints : if op = plus
  968.               then emit(152)
  969.               else emit(153);
  970.        reals: if op = plus
  971.               then emit(154)
  972.               else emit(155)
  973.             end {case}
  974.  
  975.           end
  976.         end {while}
  977.       end { simpleexpression } ;
  978.  
  979.     begin { expression }
  980.       simpleexpression(fsys+[eql,neq,lss,leq,gtr,geq], x);
  981.       if sy in [eql,neq,lss,leq,gtr,geq]
  982.       then begin
  983.         op := sy;
  984.         insymbol;
  985.         simpleexpression(fsys, y);
  986.         if (x.typ in [notyp,ints,bools,chars]) and (x.typ = y.typ)
  987.         then case op of
  988.  
  989.              eql: emit(145);
  990.              neq: emit(146);
  991.              lss: emit(147);
  992.              leq: emit(148);
  993.              gtr: emit(149);
  994.              geq: emit(150);
  995.  
  996.              end
  997.         else begin
  998.           if x.typ = ints
  999.           then begin
  1000.             x.typ := reals;
  1001.             emit1(26,1)
  1002.           end else if y.typ = ints
  1003.                    then begin
  1004.                      y.typ := reals;
  1005.                      emit1(26,0)
  1006.                    end ;
  1007.           if (x.typ=reals) and (y.typ=reals)
  1008.           then case op of
  1009.  
  1010.                eql: emit(139);
  1011.                neq: emit(140);
  1012.                lss: emit(141);
  1013.                leq: emit(142);
  1014.                gtr: emit(143);
  1015.                geq: emit(144);
  1016.  
  1017.                end
  1018.           else if (x.typ in [chars,strngs]) and (y.typ in [chars,strngs])
  1019.                then begin
  1020.                  if x.typ=strngs then t := 1 else t := 0;
  1021.                  if y.typ=strngs then t := t+2;
  1022.                  if x.temp then t := t+4;
  1023.                  if y.temp then t := t+8;
  1024.                  if op in [eql,leq,geq] then t := t+16;
  1025.                  if op in [neq,gtr,geq] then t := t+32;
  1026.                  if op in [neq,lss,leq] then t := t+64;
  1027.                  emit1(32,t);
  1028.                end
  1029.                else error(35)
  1030.              end ;
  1031.              x.typ := bools
  1032.       end
  1033.  end { expression } ;
  1034.  
  1035.     procedure assignment(lv,ad: integer);
  1036.  
  1037.     var    x,y: item;
  1038.            f  : integer;
  1039.     begin              { tab[i].obj in [vvariable,funktion] }
  1040.       x.typ := tab[i].typ;
  1041.       x.ref := tab[i].ref;
  1042.       if tab[i].normal then f := 0 else f := 1;
  1043.       emit2(f, lv, ad);
  1044.       if sy in [lbrack,lparent,period]
  1045.       then if x.typ<>strngs
  1046.            then selector([becomes,eql]+fsys, x)
  1047.            else error(60);
  1048.       if sy = becomes
  1049.       then insymbol
  1050.       else begin
  1051.         error(51);
  1052.         if sy = eql then insymbol
  1053.       end ;
  1054.  
  1055.       expression(fsys, y);
  1056.       if x.typ = y.typ
  1057.       then if x.typ in stantyps
  1058.            then if x.typ=strngs
  1059.                 then if y.temp then emit(166)
  1060.                                else emit(169)
  1061.                 else emit(138)
  1062.            else if x.ref <> y.ref
  1063.                 then error(46)
  1064.                 else if x.typ = arrays
  1065.                      then emit1(23,atab[x.ref].size)
  1066.                      else emit1(23,btab[x.ref].vsize)
  1067.       else if (x.typ=reals) and (y.typ=ints)
  1068.       then begin
  1069.         emit1(26,0);
  1070.         emit(138) end
  1071.       else if (x.typ=chars) and (y.typ=strngs)
  1072.            then begin
  1073.                   if y.temp then t := 8 else t := 0;
  1074.                   emit1(31,t); end
  1075.       else if (x.typ=strngs) and (y.typ=chars)
  1076.            then emit(168)
  1077.       else if (x.typ=strngs) and (y.typ=arrays)
  1078.            then if atab[y.ref].eltyp = chars
  1079.                 then begin emit1(167,atab[y.ref].size); emit(166) end
  1080.                 else
  1081.       else if (x.typ=arrays) and (y.typ=strngs)
  1082.            then if atab[x.ref].eltyp = chars
  1083.                 then if y.temp then emit1(175,atab[x.ref].size)
  1084.                                else emit1(174,atab[x.ref].size)
  1085.                 else
  1086.       else if (x.typ<>notyp) and (y.typ<>notyp)
  1087.            then error(46)
  1088.     end { assignment } ;
  1089.  
  1090.     procedure compoundstatement;
  1091.  
  1092.     begin
  1093.       insymbol;
  1094.       statement([semicolon,endsy]+fsys);
  1095.       while sy in [semicolon]+statbegsys do
  1096.       begin
  1097.         if sy = semicolon
  1098.         then insymbol
  1099.         else error(14);
  1100.         statement([semicolon,endsy]+fsys)
  1101.       end ;
  1102.       if sy = endsy then insymbol else error(57)
  1103.     end { compoundstatement } ;
  1104.  
  1105.     procedure ifstatement;
  1106.  
  1107.     var    x: item;
  1108.            lc1,lc2: integer;
  1109.     begin
  1110.       insymbol;
  1111.       expression(fsys+[thensy,dosy], x);
  1112.       if not (x.typ in [bools,notyp])
  1113.       then error(17);
  1114.       lc1 := lc;
  1115.       emit(11);     { jmpc }
  1116.  
  1117.       if sy = thensy
  1118.       then insymbol
  1119.       else begin
  1120.         error(52);
  1121.         if sy = dosy
  1122.         then insymbol
  1123.       end ;
  1124.  
  1125.       statement(fsys+[elsesy]);
  1126.  
  1127.       if sy = elsesy
  1128.       then begin
  1129.         insymbol;                lc2 := lc;
  1130.         emit(10);        code[lc1].y := lc;
  1131.         statement(fsys); code[lc2].y := lc
  1132.       end
  1133.       else code[lc1].y := lc
  1134.     end { ifstatement } ;
  1135.  
  1136.     procedure casestatement;
  1137.  
  1138.     var    x: item;
  1139.     i,j,k,lc1: integer;
  1140.     casetab: array [1..csmax] of
  1141.               packed record
  1142.                 val, lc: index
  1143.               end ;
  1144.     exittab: array [1..csmax] of integer;
  1145.  
  1146.       procedure caselabel;
  1147.  
  1148.       var    lab: conrec;
  1149.              k  : integer;
  1150.       begin
  1151.         constant(fsys+[comma,colon], lab);
  1152.         if lab.tp <> x.typ
  1153.         then error(47)
  1154.         else if i = csmax
  1155.              then fatal(6)
  1156.              else begin
  1157.                i := i+1;    k := 0;
  1158.                casetab[i].val :=lab.i;
  1159.                casetab[i].lc  := lc;
  1160.                repeat
  1161.                  k := k+1
  1162.                until casetab[k].val = lab.i;
  1163.  
  1164.                if k < i then error(1);   { multiple definition }
  1165.              end
  1166.       end { caselabel } ;
  1167.  
  1168.       procedure onecase;
  1169.  
  1170.       begin
  1171.         if sy in constbegsys
  1172.         then begin
  1173.           caselabel;
  1174.           while sy = comma do
  1175.           begin
  1176.             insymbol; caselabel
  1177.           end ;
  1178.           if sy = colon
  1179.           then insymbol else error(5);
  1180.           statement([semicolon,endsy]+fsys);
  1181.           j := j+1;
  1182.           exittab[j] := lc; emit(10)
  1183.         end
  1184.       end { onecase } ;
  1185.  
  1186.     begin {casestatement}
  1187.       insymbol;
  1188.       i := 0;   j := 0;
  1189.       expression(fsys+[ofsy,comma,colon], x);
  1190.       if not (x.typ in [ints,bools,chars,notyp])
  1191.       then error(23);
  1192.       lc1 := lc; emit(12);  { jmpx }
  1193.  
  1194.       if sy = ofsy then insymbol else error(8);
  1195.       onecase;
  1196.       while sy = semicolon do
  1197.       begin
  1198.         insymbol;
  1199.         onecase
  1200.       end ;
  1201.       code[lc1].y := lc;
  1202.       for k := 1 to i do
  1203.       begin
  1204.         emit1(13,casetab[k].val);
  1205.         emit1(13,casetab[k].lc)
  1206.       end ;
  1207.       emit1(10,0);
  1208.       for k := 1 to j do code[exittab[k]].y := lc;
  1209.       if sy = endsy then insymbol else error(57)
  1210.     end { casestatement } ;
  1211.  
  1212.     procedure repeatstatement;
  1213.  
  1214.     var    x  : item;
  1215.            lc1: integer;
  1216.     begin
  1217.       lc1 := lc;
  1218.       insymbol;
  1219.       statement([semicolon,untilsy]+fsys);
  1220.       while sy in [semicolon]+statbegsys do
  1221.       begin
  1222.         if sy = semicolon then insymbol else error(14);
  1223.         statement([semicolon,untilsy]+fsys)
  1224.       end ;
  1225.       if sy = untilsy
  1226.       then begin
  1227.         insymbol;
  1228.         expression(fsys, x);
  1229.         if not (x.typ in [bools,notyp]) then error(17);
  1230.         emit1(11, lc1)
  1231.       end else error(53)
  1232.     end { repeatstatement } ;
  1233.  
  1234.     procedure whilestatement;
  1235.  
  1236.     var    x: item;
  1237.            lc1,lc2: integer;
  1238.     begin
  1239.       insymbol;
  1240.       lc1 := lc;
  1241.       expression(fsys+[dosy], x);
  1242.       if not (x.typ in [bools,notyp]) then error(17);
  1243.       lc2 := lc; emit(11);
  1244.  
  1245.       if sy = dosy then insymbol else error(54);
  1246.       statement(fsys);
  1247.       emit1(10,lc1);
  1248.       code[lc2].y := lc
  1249.     end { whilestatement } ;
  1250.  
  1251.     procedure forstatement;
  1252.  
  1253.     var    cvt: types;
  1254.            x  : item;
  1255.            i,f,lc1,lc2: integer;
  1256.     begin
  1257.       insymbol;
  1258.       if sy = ident
  1259.       then begin
  1260.         i := loc(id);
  1261.         insymbol;
  1262.         if i = 0
  1263.         then cvt := ints
  1264.         else if tab[i].obj = vvariable
  1265.              then begin
  1266.                cvt := tab[i].typ;
  1267.                if tab[i].normal then f := 0 else f := 1;
  1268.                emit2(f, tab[i].lev, tab[i].adr);
  1269.                if not (cvt in [notyp,ints,bools,chars]) then error(18)
  1270.              end else begin
  1271.                error(37); cvt := ints
  1272.              end
  1273.       end else skip([becomes,tosy,downtosy,dosy]+fsys, 2);
  1274.  
  1275.       if sy = becomes
  1276.       then begin
  1277.         insymbol;
  1278.         expression([tosy,downtosy,dosy]+fsys, x);
  1279.         if x.typ <> cvt then error(19);
  1280.       end else skip([tosy,downtosy,dosy]+fsys, 51);
  1281.       f := 14;
  1282.  
  1283.       if sy in [tosy, downtosy]
  1284.       then begin
  1285.         if sy = downtosy then f := 16;
  1286.         insymbol;
  1287.         expression([dosy]+fsys, x);
  1288.         if x.typ <> cvt then error(19)
  1289.       end else skip([dosy]+fsys, 55);
  1290.  
  1291.       lc1 := lc; emit(f);
  1292.       if sy = dosy then insymbol else error(54);
  1293.       lc2 := lc;
  1294.       statement(fsys);
  1295.       emit1(f+1,lc2);
  1296.       code[lc1].y := lc
  1297.     end { forstatement } ;
  1298.  
  1299.     procedure standproc(n: integer);
  1300.  
  1301.     var    i,f: integer;
  1302.            x,y: item;
  1303.     begin
  1304.  
  1305.       case n of
  1306.  
  1307.  1,2: begin { read }
  1308.         if sy = lparent
  1309.         then begin
  1310.           repeat
  1311.             insymbol;
  1312.             if sy <> ident
  1313.             then error(2)
  1314.             else begin
  1315.               i := loc(id);
  1316.               insymbol;
  1317.               if i <> 0
  1318.               then if tab[i].obj <> vvariable
  1319.                    then error( 37)
  1320.                    else begin
  1321.                      x.typ := tab[i].typ;
  1322.                      x.ref := tab[i].ref;
  1323.                      if tab[i].normal then f := 0 else f := 1;
  1324.                      emit2(f, tab[i].lev, tab[i].adr);
  1325.                      if sy in [lbrack,lparent,period]
  1326.                      then begin
  1327.                             if x.typ=strngs then error(60);
  1328.                             selector(fsys+[comma,rparent], x); end;
  1329.                      if x.typ in [ints,reals,chars,strngs,notyp]
  1330.                      then emit1(27,ord(x.typ))
  1331.                      else error(41)
  1332.                    end
  1333.             end ;
  1334.             test([comma,rparent], fsys, 6);
  1335.           until sy <> comma;
  1336.  
  1337.           if sy = rparent then insymbol else error(4)
  1338.         end ;
  1339.         if n = 2 then emit(162)
  1340.       end ;
  1341.  3,4: begin { write }
  1342.         if sy = lparent
  1343.         then begin
  1344.           repeat
  1345.             insymbol;
  1346.             expression(fsys+[comma,colon,rparent], x);
  1347.             if not (x.typ in stantyps) then error(41);
  1348.             if sy = colon
  1349.             then begin
  1350.               insymbol;
  1351.               expression(fsys+[comma,colon,rparent], y);
  1352.               if y.typ <> ints then error(43);
  1353.               if sy = colon
  1354.               then begin
  1355.                 if x.typ <> reals then error( 42);
  1356.                 insymbol;
  1357.                 expression(fsys+[comma,rparent], y);
  1358.                 if y.typ <> ints then error(43);
  1359.                 emit(137)
  1360.               end else begin
  1361.                 if x.typ=strngs
  1362.                 then if x.temp then emit(177) else emit(176)
  1363.                 else emit1(30, ord(x.typ))
  1364.               end
  1365.             end else if x.typ=strngs
  1366.                      then if x.temp then emit(171)
  1367.                                     else emit(170)
  1368.                      else emit1(29, ord(x.typ))
  1369.           until sy <> comma;
  1370.           if sy = rparent then insymbol else error(4)
  1371.         end ;
  1372.         if n = 4 then emit(163)
  1373.       end ; {write}
  1374.  
  1375.    5: emit(131); { halt }
  1376.  
  1377.    6: emit1(8,43); { randomize }
  1378.  
  1379.    7: emit1(8,44); { clrscr }
  1380.  
  1381.    8: begin  { gotoxy }
  1382.         if sy = lparent then insymbol else error(9);
  1383.         expression(fsys+[comma,rparent], x);
  1384.         if x.typ<>ints then error(43);
  1385.         test([comma],fsys+[rparent],59);
  1386.         if sy = comma
  1387.         then begin
  1388.           insymbol;
  1389.           expression(fsys+[rparent], y);
  1390.           if y.typ<>ints then error(43);
  1391.           emit1(8,45);
  1392.         end;
  1393.         if sy = rparent then insymbol else error(4);
  1394.       end;
  1395.  
  1396. 9,10,11,12:
  1397.       begin
  1398.         if sy = lparent then insymbol else error(9);
  1399.         expression(fsys+[rparent], x);
  1400.         if x.typ<>ints then error(43);
  1401.         case n of
  1402.        9: emit1(8,46);  { textcolor }
  1403.       10: emit1(8,50);  { delay }
  1404.       11: emit1(8,51);  { textbackground }
  1405.       12: emit1(8,52);  { sound }
  1406.         end;
  1407.         if sy = rparent then insymbol else error(4);
  1408.       end;
  1409.  
  1410.   13: emit1(8,53);  { nosound }
  1411.  
  1412.       end { case }
  1413.     end { standproc } ;
  1414.  
  1415.   begin { statement }
  1416.     if sy in statbegsys+[ident]
  1417.     then case sy of
  1418.  
  1419.        ident: begin
  1420.                 i := loc(id);
  1421.                 insymbol;
  1422.                 if i <> 0
  1423.                 then case tab[i].obj of
  1424.  
  1425.          konstant, type1: error(45);
  1426.                vvariable: assignment(tab[i].lev, tab[i].adr);
  1427.                prozedure: if tab[i].lev <> 0
  1428.                           then call(fsys, i)
  1429.                           else standproc(tab[i].adr);
  1430.                 funktion: if tab[i].ref = display[level]
  1431.                           then assignment(tab[i].lev+1, 0)
  1432.                           else error(45)
  1433.                      end {case}
  1434.  
  1435.               end ;
  1436.  
  1437.      beginsy: compoundstatement;
  1438.         ifsy: ifstatement;
  1439.       casesy: casestatement;
  1440.      whilesy: whilestatement;
  1441.     repeatsy: repeatstatement;
  1442.        forsy: forstatement;
  1443.  
  1444.          end; {case}
  1445.  
  1446.     test(fsys, [], 14)
  1447.   end { statement } ;
  1448.  
  1449. begin { block }
  1450.   dx := 6; prt := t;
  1451.   if level > lmax then fatal(5);
  1452.   test([lparent,colon,semicolon], fsys, 14);
  1453.  
  1454.   enterblock;
  1455.            prb := b;      display[level] := b;
  1456.   tab[prt].typ := notyp;    tab[prt].ref := prb;
  1457.   if (sy = lparent) and (level > 1) then parameterlist;
  1458.   btab[prb].lastpar := t;btab[prb].psize := dx;
  1459.  
  1460.   if isfun
  1461.   then if sy = colon
  1462.        then begin
  1463.          insymbol;   { function type }
  1464.          if sy = ident
  1465.          then begin
  1466.            x := loc(id);
  1467.            insymbol;
  1468.            if x <> 0
  1469.            then if tab[x].obj <> type1
  1470.                 then error(29)
  1471.                 else if tab[x].typ in stantyps
  1472.                      then tab[prt].typ := tab[x].typ
  1473.                      else error(15)
  1474.          end else skip([semicolon]+fsys, 2)
  1475.        end else error(5);
  1476.   if sy = semicolon then insymbol else error(14);
  1477.  
  1478.   repeat
  1479.     if sy = constsy then constdec;
  1480.     if sy = typesy then typedeclaration;
  1481.     if sy = varsy then variabledeclaration;
  1482.     btab[prb].vsize := dx;
  1483.     while sy in [procsy,funcsy] do procdeclaration;
  1484.     test([beginsy], blockbegsys+statbegsys, 56)
  1485.   until sy in statbegsys;
  1486.  
  1487.   tab[prt].adr := lc;
  1488.   insymbol;
  1489.   statement([semicolon,endsy]+fsys);
  1490.  
  1491.   while sy in [semicolon]+statbegsys do
  1492.   begin
  1493.     if sy = semicolon then insymbol else error(14);
  1494.     statement([semicolon,endsy]+fsys)
  1495.   end ;
  1496.   if sy = endsy then insymbol else error(57);
  1497.   test(fsys+[period], [], 6)
  1498. end { block } ;
  1499.  
  1500.